#include "tile.h"
#include "CppSQLite3.h"

TileFile::TileFile(const char *filename, ushort w, ushort h)
{
        m_TileBase = load_bitmap(filename, NULL);
        if (m_TileBase == NULL)
                throw LOAD_TILE_FAILED;

        m_w = w;
        m_h = h;
}

TileFile::~TileFile()
{
        if (m_TileBase) {
                destroy_bitmap(m_TileBase);
        }
}


BITMAP * TileFile::getTile(ushort x, ushort y)
{
        if (m_TileBase)
        {
                return create_sub_bitmap(m_TileBase, x*m_w, y*m_h, m_w, m_h);
        }

        return NULL;
}

BITMAP *TileFile::getTile(const Rect &rect)
{
        if (m_TileBase)
        {
                return create_sub_bitmap(m_TileBase, rect.x, rect.y, rect.w, rect.h);
        }

        return NULL;
}

TileManager::TileManager()
{
    memset(m_tileFiles, 0, sizeof(m_tileFiles));
}

TileManager::~TileManager()
{
    map <ushort, BITMAP *>::iterator it, end = m_tiles.end();
    for (it = m_tiles.begin(); it != end; ++it) {
        destroy_bitmap(it->second);
    }

    for (size_t i = 0; i < MAX_TILE_FILES; ++i) {
        if (m_tileFiles[i])
            delete (m_tileFiles[i]);
    }
}

bool TileManager::LoadFile(const char *filename, ushort w, ushort h, ushort fid)
{
    assert(fid < MAX_TILE_FILES);
    if (m_tileFiles[fid]) {
        allegro_message("reload Tile file %s", filename);
        return false;
    }

    try {
        m_tileFiles[fid] = new TileFile(filename, w, h);
    } catch (...) {
        allegro_message("load Tile file %s failed!", filename);
        return false;
    }

    return true;
}

void TileManager::LoadTileDB(const char *dbfile)
{
    try {
        CppSQLite3DB db;
        db.open(dbfile);
        if (!db.tableExists("Tile")) {
            allegro_message("DB Tale Tile not exsit");
            return ;
        }

        int id, mapid, x, y, w, h;
        CppSQLite3Query q = db.execQuery("SELECT * FROM Tile");
        while (!q.eof()) {
            id     = q.getIntField(0);
            mapid  = q.getIntField(1);
            x      = q.getIntField(2);
            y      = q.getIntField(3);
            w      = q.getIntField(4);
            h      = q.getIntField(5);

            if (mapid >= MAX_TILE_FILES || m_tileFiles[mapid] == NULL) {
                allegro_message("DB Tale Tile : Error Mapid");
                q.nextRow();
                continue;
            }

            if (w == 0 || h == 0)
                m_tiles[id] = m_tileFiles[mapid]->getTile(x, y);
            else
                m_tiles[id] = m_tileFiles[mapid]->getTile(Rect(x, y, w, h));

            q.nextRow();
        }
    }
    catch (CppSQLite3Exception &e) {
        allegro_message("Load Tile Info with Exception happend!");
        return ;
    }
}

BITMAP *TileManager::getTile(ushort tid)
{
    map <ushort, BITMAP *>::iterator it = m_tiles.find(tid);
    if (it == m_tiles.end())
        return NULL;
    return it->second;
}
